package com.zxq.ai.domain.service;

import com.zxq.common.middleware.DistributedID;
import com.zxq.common.utils.DateUtil;
import com.zxq.common.utils.NullUtil;
import com.zxq.ai.domain.activity.Activity;
import com.zxq.ai.domain.activity.ActivityParticipantRecord;
import com.zxq.ai.domain.enums.ActivityParticipantRecordStatus;
import com.zxq.ai.domain.enums.RewardRedeemTaskStatus;
import com.zxq.ai.domain.exception.ActivityHasEndedException;
import com.zxq.ai.domain.exception.ActivityRewardConditionNotExistException;
import com.zxq.ai.domain.exception.NotMeetRewardCondition;
import com.zxq.ai.domain.reward.RewardCondition;
import com.zxq.ai.domain.reward.RewardRedeemTask;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.function.Function;

@Service
public class ActivityDomain {

    @Resource
    private DistributedID distributedID;

    /**
     * 兑换奖励：校验 recordList 是否符合 activity 的兑换规则
     *
     * @param activity
     * @param recordList
     * @param operatorUserId 操作人ID
     */
    public Pair<RewardRedeemTask, List<ActivityParticipantRecord>> redeemReward(Activity activity, List<? extends ActivityParticipantRecord> recordList, Long operatorUserId) {
        RewardCondition rewardCondition = activity.getRewardCondition();
        if (rewardCondition == null) {
            throw new ActivityRewardConditionNotExistException(String.format("活动[%s]未配置奖励条件", activity.getActivityId()));
        }

        if (NullUtil.defaultIfNull(activity.getRewardCount(), 0) >= NullUtil.defaultIfNull(activity.getRewardNum(), 0)) {
            throw new ActivityHasEndedException(String.format("来晚啦~ 活动[%s]奖励已经被抢光了", activity.getActivityId()));
        }

        // 过滤出未兑换的record
        List<ActivityParticipantRecord> canRedeemRecordList = recordList.stream()
                .filter(e -> e.getStatus() == ActivityParticipantRecordStatus.NOT_REDEEMED)
                .map(e -> (ActivityParticipantRecord) e)
                .toList();
        if (CollectionUtils.size(canRedeemRecordList) < rewardCondition.getThreshold()) {
            throw new NotMeetRewardCondition(String.format("未达成活动[%s]兑换条件", activity.getActivityId()));
        }

        // - 创建兑换任务
        RewardRedeemTask redeemTask = RewardRedeemTask.builder()
                .taskId(distributedID.nextId())
                .activityType(activity.getActivityType())
                .activityId(activity.getActivityId())
                .payeeUserId(operatorUserId)
                .payerUserId(activity.getOwnerUserId())
                .rewardType(activity.getRewardType())
                .rewardAmount(activity.getRewardAmount())
                .status(RewardRedeemTaskStatus.INIT)
                .createAt(DateUtil.millis())
                .createBy(String.valueOf(operatorUserId))
                .updateAt(DateUtil.millis())
                .updateBy(String.valueOf(operatorUserId))
                .build();

        for (int i = 0; i < rewardCondition.getThreshold(); i++) {
            recordList.get(i).setRewardRedeemTaskId(redeemTask.getTaskId());
            recordList.get(i).setStatus(ActivityParticipantRecordStatus.REDEEMED);
            recordList.get(i).setUpdateAt(DateUtil.millis());
            recordList.get(i).setUpdateBy(String.valueOf(operatorUserId));
        }

        // 此次兑换的卡片
        List<ActivityParticipantRecord> redeemRecordList = canRedeemRecordList.stream()
                .filter(e -> e.getStatus() == ActivityParticipantRecordStatus.REDEEMED)
                .toList();

        return Pair.of(redeemTask, redeemRecordList);
    }

    /**
     * 是否符合奖励兑换条件
     * @param input
     * @param function
     * @return
     * @param <T>
     * @param <R>
     */
    public <T, R> R redeemReward(T input, Function<T, R> function) {
        return function.apply(input);
    }

}
